﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 优惠券历史记录接口实现
    /// </summary>
    public class ShopCouponHistoryService : BaseService, IShopCouponHistoryService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;
        public ShopCouponHistoryService(IDbContextFactory contentFactory,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取记录总数量
        /// </summary>
        public async Task<int> QueryCountAsync(Expression<Func<ShopCouponHistory, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            return await _context.Set<ShopCouponHistory>()
                .Include(x => x.ShopCoupon).Where(funcWhere).CountAsync();
        }

        /// <summary>
        /// 查询指定数量列表
        /// </summary>
        public async Task<IEnumerable<ShopCouponHistory>> QueryListAsync(int top, Expression<Func<ShopCouponHistory, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<ShopCouponHistory>()
                .Include(x => x.ShopCoupon)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<ShopCouponHistory>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<ShopCouponHistory, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<ShopCouponHistory>()
                .Include(x => x.ShopCoupon)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<ShopCouponHistory>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 会员领取优惠券
        /// </summary>
        public async Task<ShopCouponHistory> AddAsync(ShopCouponHistoryEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取登录用户ID
            var userModel = await _userService.GetUserAsync();
            if (userModel == null)
            {
                throw new ResponseException("账户尚未登录", ErrorCode.TokenExpired, StatusCodes.Status401Unauthorized);
            }
            var memberModel = await _context.Set<Members>().FirstOrDefaultAsync(x => x.UserId == userModel.Id);
            if (memberModel == null)
            {
                throw new ResponseException("会员账户不存在或已删除");
            }
            //检查用户是否领取
            if (await _context.Set<ShopCouponHistory>().FirstOrDefaultAsync(x => x.Status == 0
                 && x.UserId == userModel.Id
                 && x.CouponId == modelDto.CouponId) != null)
            {
                throw new ResponseException("已领取过该优惠券");
            }
            //查询优惠券信息
            var couponModel = await _context.Set<ShopCoupon>().FirstOrDefaultAsync(x => x.IsDelete == 0
                && x.Id == modelDto.CouponId
                && DateTime.Compare(x.EnableTime, DateTime.Now) <= 0
                && DateTime.Compare(x.EndTime, DateTime.Now) >= 0);
            if (couponModel == null)
            {
                throw new ResponseException("优惠券暂不可用或已过期");
            }
            if (couponModel.ReceiveCount >= couponModel.PublishCount)
            {
                throw new ResponseException("优惠券已领完");
            }
            if (couponModel.Point > memberModel.Point)
            {
                throw new ResponseException("积分不足，无法兑换优惠券");
            }

            //扣取会员积分
            if (couponModel.Point > 0)
            {
                //增加会员积分记录
                await _context.Set<MemberPointLog>().AddAsync(new MemberPointLog
                {
                    UserId = memberModel.UserId,
                    Value = couponModel.Point * -1,
                    Remark = $"兑换优惠券，优惠券ID:{couponModel.Id}"
                });
                //扣减会员账户积分
                memberModel.Point -= couponModel.Point;
                _context.Set<Members>().Update(memberModel);
            }
            //更改优惠券信息
            couponModel.ReceiveCount++;
            _context.Set<ShopCoupon>().Update(couponModel);
            //添加优惠券领取记录
            var model = _mapper.Map<ShopCouponHistory>(modelDto);
            model.UserId = userModel.Id;
            model.UserName = userModel.UserName;
            model.Type = 1;
            model.AddTime = DateTime.Now;
            await _context.Set<ShopCouponHistory>().AddAsync(model);
            //统一保存到数据库
            var result = await this.SaveAsync();
            if (!result)
            {
                throw new ResponseException("数据保存时发生意外错误");
            }
            //映射成DTO
            return _mapper.Map<ShopCouponHistory>(model);
        }

        /// <summary>
        /// 查询会员可用购物券
        /// </summary>
        public async Task<IEnumerable<ShopCouponHistory>> QueryListAsync(int? merchantId, List<ShopCartEditDto> buyList, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取当前用户信息
            var userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                throw new ResponseException("会员尚未登录或已超时", ErrorCode.TokenExpired, StatusCodes.Status401Unauthorized);
            }
            //获取商品列表
            var productList = await _context.Set<ShopGoodsProduct>()
                    .Where(x => buyList.Select(p => p.ProductId).Contains(x.Id))
                    .Include(x => x.ShopGoods)
                    .ToListAsync();
            if (productList == null)
            {
                throw new ResponseException("未查询到商品信息");
            }
            //创建购买商品列表
            List<ShopCartBuyDto> cartList = new();
            //遍历商品重新赋值
            foreach(var item in productList)
            {
                var buyModel = buyList.FirstOrDefault(x => x.ProductId == item.Id);
                ShopCartBuyDto modelt = new()
                {
                    GoodsId = item.GoodsId,
                    ProductId = item.Id,
                    SellPrice = item.SellPrice,
                    Quantity = buyModel != null ? buyModel.Quantity : 0
                };
                cartList.Add(modelt);
            }
            //获取用户可用的购物券列表
            var historyCouponList = await _context.Set<ShopCouponHistory>()
                .Include(x => x.ShopCoupon).ThenInclude(x => x!.GoodsRelations)
                .Where(x => x.UserId == userId
                    && x.Status == 0
                    && x.IsUse == 0
                    && x.ShopCoupon != null
                    && x.ShopCoupon.MerchantId == merchantId.GetValueOrDefault()
                    && x.ShopCoupon.IsDelete == 0
                    && DateTime.Compare(x.ShopCoupon.StartTime, DateTime.Now) <= 0
                    && DateTime.Compare(x.ShopCoupon.EndTime, DateTime.Now) >= 0)
                .ToListAsync();
            //创建一个用于存放可用的购物券列表
            List<ShopCouponHistory> resultList = new();
            //遍历购物券，查找与商品匹配的购物券加入到可用购物券列表
            foreach (var modelt in historyCouponList)
            {
                //0.店铺券
                if (modelt.ShopCoupon?.UseType == 0)
                {
                    //如果不限金额或商品金额大于等于购物券设定的值则有效
                    if (modelt.ShopCoupon.MinAmount == 0 || cartList.Select(x => x.SellPrice * x.Quantity).Sum() >= modelt.ShopCoupon.MinAmount)
                    {
                        resultList.Add(modelt);
                    }
                }
                //1.商品券
                else if (modelt.ShopCoupon?.UseType == 1)
                {
                    //取出优惠券可用商品ID
                    var couponGoodsIds = modelt.ShopCoupon.GoodsRelations.Select(x => x.GoodsId);
                    //查找符合条件的商品
                    var goodsIds = productList.Where(x => couponGoodsIds.Contains(x.GoodsId)).Select(x => x.GoodsId);
                    if (goodsIds != null
                        && cartList.Where(x => goodsIds.Contains(x.GoodsId)).Select(x => x.SellPrice * x.Quantity).Sum() >= modelt.ShopCoupon.MinAmount)
                    {
                        resultList.Add(modelt);
                    }
                }
            }
            return resultList;
        }

    }
}
